package com.h2.common.util.email.javax;

import java.util.Collection;
import java.util.Properties;

import javax.mail.Address;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.h2.common.util.email.impl.AEmailProvider;
import com.h2.common.util.email.impl.SmtpUtils;

/**
 * A default implementation of {@link com.h2.common.util.email.IEmailProvider} that
 * uses javax's standard SMTP protocol.
 * 
 * @since 2.1
 */
public class DefaultEmailProvider extends AEmailProvider {
   
   private static final Logger LOG = LoggerFactory.getLogger(DefaultEmailProvider.class);
   
   private Properties _sessionProperties;
   
   private Boolean _sessionDebug = Boolean.FALSE;
   
   ////
   ////
   
   public DefaultEmailProvider() {
      setSessionProperties(new Properties());
   }
   
   /* (non-Javadoc)
    * @see com.pv.sdm.util.email.impl.AEmailProvider#send(java.lang.String,
    *    java.lang.String, java.lang.String, java.util.Collection,
    *    java.util.Collection)
    */
   @Override
   public boolean send(String subject, String message, String contentType,
         Collection<String> from, Collection<String> to) {
      
      try {
         
         //check for null to/from addresses
         if(!super.send(subject, message, contentType, from, to)) {
            return false;
         }
   
         // create some properties and get the default Session
         Session session = Session.getDefaultInstance(getSessionProperties(),
               null);
         session.setDebug(getSessionDebug());
         
         // create a message
         Message msg = new MimeMessage(session);
   
         // set the from addresses
         addFromAddresses(msg, SmtpUtils.toInternetAddress(from));
         
         // set the to addresses
         addToAddresses(msg, SmtpUtils.toInternetAddress(to));
   
         // Setting the Subject and Content Type
         msg.setSubject(subject);
         msg.setContent(message, contentType);
         
         sendMessage(msg);
      
      } catch (MessagingException exp) {
         LOG.error(exp.getMessage());
         LOG.debug("Details: ", exp);
         return false;
      }
      return true;
   }
   
   protected void addFromAddresses(Message message,
         Collection<InternetAddress> addresses) throws MessagingException {
      message.addFrom(addresses.toArray(new Address[addresses.size()]));
   }
   
   protected void addToAddresses(Message message,
         Collection<InternetAddress> addresses) throws MessagingException {
      message.setRecipients(Message.RecipientType.TO,
            addresses.toArray(new Address[addresses.size()]));
   }
   
   protected void sendMessage(Message message) throws MessagingException {
      Transport.send(message);
   }
   
   @Override
   public void setHost(String host) {
      super.setHost(host);
      getSessionProperties().put(SmtpUtils.SMTP_HOST_PROPERTY, host);
   }

   /**
    * @return the sessionProperties
    */
   public Properties getSessionProperties() {
      return _sessionProperties;
   }

   /**
    * @param sessionProperties the sessionProperties to set
    */
   protected void setSessionProperties(Properties sessionProperties) {
      _sessionProperties = sessionProperties;
   }

   /**
    * @return the sessionDebug
    */
   public Boolean getSessionDebug() {
      return _sessionDebug;
   }

   /**
    * @param sessionDebug the sessionDebug to set
    */
   public void setSessionDebug(Boolean sessionDebug) {
      _sessionDebug = sessionDebug;
   }
}
